/*
 * jxUtils Project (2014)
 * 
 * by Denilson Edinaldo Pinto
 * 
 * LGPL
 * Copyright (C) 2014
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.jxUtils.system;

import java.io.File;
import java.math.BigDecimal;

import org.jxUtils.exception.InvalidValueException;
import org.jxUtils.file.FileSize;
import org.jxUtils.file.FileSize.TYPE;
import org.jxUtils.lang.StringAsync;

/**
 * @author Denilson Edinaldo Pinto
 * @porject jxUtils
 * @package org.jxUtils.system
 * @date 15/11/2014 - 19:58:13
 */
public final class HardDiscUtil {
	
	public static final double PERCENT_TOTAL_SPACE = 100.00;
	
	/**
	 * @return driveFile
	 */
	public static File getDriveFile() {
	
		return new File(getDriveName());
	}
	
	/**
	 * @return driveName
	 */
	public static String getDriveName() {
	
		File drive = new File(HardDiscUtil.class.getResource("").getPath());
		
		//
		for(File file : getRoots()) {
			
			//
			if(drive.getPath().contains(file.toString())) {
				
				return file.toString();
			}
		}
		
		return "";
	}
	
	/**
	 * @return roots
	 */
	public static File[] getRoots() {
	
		return File.listRoots();
	}
	
	/**
	 * @return the freeSize
	 */
	public static long getFreeSize() {
	
		return getDriveFile().getFreeSpace();
	}
	
	/**
	 * @return the freeSize
	 */
	public static String getFreeSizeFormated() {
	
		try {
			//
			return new FileSize(getFreeSize(), TYPE.IEC).toString();
			
		}catch(InvalidValueException invalidValueException) {
			// ignore
		}
		
		return "";
	}
	
	/**
	 * @return the noUsableSize
	 */
	public static long getNoUsableSize() {
	
		return getFreeSize() - getUsableSize();
	}
	
	/**
	 * @return the noUsableSize
	 */
	public static String getNoUsableSizeFormated() {
	
		try {
			//
			return new FileSize(getNoUsableSize(), TYPE.IEC).toString();
			
		}catch(InvalidValueException invalidValueException) {
			// ignore
		}
		
		return "";
	}
	
	/**
	 * @return the freeSize
	 */
	public static double getPercentFreeSize(int precision) {
	
		try {
			//
			return new BigDecimal((getFreeSize() * PERCENT_TOTAL_SPACE) / getTotalSize()).setScale(precision, BigDecimal.ROUND_UP).doubleValue();
			
		}catch(InvalidValueException invalidValueException) {
			// ignore
		}
		
		return 0;
	}
	
	/**
	 * @return the noUsableSize
	 */
	public static double getPercentNoUsableSize(int precision) {
	
		try {
			//
			return new BigDecimal((getNoUsableSize() * PERCENT_TOTAL_SPACE) / getTotalSize()).setScale(precision, BigDecimal.ROUND_UP).doubleValue();
			
		}catch(InvalidValueException invalidValueException) {
			// ignore
		}
		
		return 0;
	}
	
	/**
	 * @return the usableSize
	 */
	public static double getPercentUsableSize(int precision) {
	
		try {
			//
			return new BigDecimal((getUsableSize() * PERCENT_TOTAL_SPACE) / getTotalSize()).setScale(precision, BigDecimal.ROUND_UP).doubleValue();
			
		}catch(InvalidValueException invalidValueException) {
			// ignore
		}
		
		return 0;
	}
	
	/**
	 * @return the usedSize
	 */
	public static double getPercentUsedSize(int precision) {
	
		try {
			return new BigDecimal((getUsedSize() * PERCENT_TOTAL_SPACE) / getTotalSize()).setScale(precision, BigDecimal.ROUND_UP).doubleValue();
			
		}catch(InvalidValueException invalidValueException) {
			// ignore
		}
		
		return 0;
	}
	
	/**
	 * @return the totalSize
	 */
	public static long getTotalSize() {
	
		return getDriveFile().getTotalSpace();
	}
	
	/**
	 * @return the totalSize
	 */
	public static String getTotalSizeFormated() {
	
		try {
			//
			return new FileSize(getTotalSize(), TYPE.IEC).toString();
			
		}catch(InvalidValueException invalidValueException) {
			// ignore
		}
		
		return "";
	}
	
	/**
	 * @return the usableSize
	 */
	public static long getUsableSize() {
	
		return getDriveFile().getUsableSpace();
	}
	
	/**
	 * @return the usableSize
	 */
	public static String getUsableSizeFormated() {
	
		try {
			//
			return new FileSize(getUsableSize(), TYPE.IEC).toString();
			
		}catch(InvalidValueException invalidValueException) {
			// ignore
		}
		
		return "";
	}
	
	/**
	 * @return the usedSize
	 */
	public static long getUsedSize() {
	
		return getTotalSize() - getFreeSize();
	}
	
	/**
	 * @return the usedSize
	 */
	public static String getUsedSizeFormated() {
	
		try {
			//
			return new FileSize(getTotalSize() - getFreeSize(), TYPE.IEC).toString();
			
		}catch(InvalidValueException invalidValueException) {
			// ignore
		}
		
		return "";
	}
	
	/**
	 * @return the usedSpace
	 * @see #getUsedSizeFormated()
	 */
	public static String getUsedSpaceFormated() {
	
		return getUsedSizeFormated();
	}
	
	@Override
	public String toString() {
	
		StringAsync str = new StringAsync();
		
		// TODO: Implementar Internacionalização
		str.appendLine("Name: " + getDriveName());
		str.appendLine("Total Size: " + getTotalSizeFormated());
		str.appendLine("Used Size: " + getUsedSizeFormated() + " (" + getPercentUsedSize(2) + "%)");
		str.appendLine("Free Size: " + getFreeSizeFormated() + " (" + getPercentFreeSize(2) + "%)");
		str.appendLine("Usable Size: " + getUsableSizeFormated() + " (" + getPercentUsableSize(2) + "%)");
		str.appendLine("No Usable Size: " + getNoUsableSizeFormated() + " (" + getPercentNoUsableSize(2) + "%)");
		
		return str.toString();
	}
}
